//////////////////////////////////////////////////////////////////////////
#include "CxError.Enums.h"
//////////////////////////////////////////////////////////////////////////
#pragma once
#pragma managed
//////////////////////////////////////////////////////////////////////////
NAMESPACE_BEGIN
//////////////////////////////////////////////////////////////////////////
public ref class CvException : public System::ApplicationException
{
private:
	static CvErrorCallback s_pLastCallBack = NULL;
	static int ExceptionErrorReport(int status, const char* func_name, const char* err_msg, const char* file_name, int line, void* userdata)
	{
		if (status != CV_StsOk)
		{
			throw gcnew CvException((ErrorCode)status, 
				System::Runtime::InteropServices::Marshal::PtrToStringAnsi(IntPtr((char*)func_name)),
				System::Runtime::InteropServices::Marshal::PtrToStringAnsi(IntPtr((char*)err_msg)),
				System::Runtime::InteropServices::Marshal::PtrToStringAnsi(IntPtr((char*)file_name)),
				line);
		}
		return 0;
	}

public:
	static void TurnRaiseException(bool on)
	{
		if (on)
		{
			s_pLastCallBack = cvRedirectError((CvErrorCallback)ExceptionErrorReport);
		}
		else
		{
			if (s_pLastCallBack != NULL)
			{
				cvRedirectError(s_pLastCallBack);
			}
		}
	}

public:
	CvException(ErrorCode status, System::String^ func, System::String^ msg, System::String^ filename, int line)
		: System::ApplicationException(msg)
	{
		_status = status;
		_func = func;
		_filename = filename;
		_line = line;
	}

public:
	property ErrorCode Status
	{
		ErrorCode get() { return _status; }
	}

	property System::String^ Function
	{
		System::String^ get() { return _func; }
	}

	property System::String^ FileName
	{
		System::String^ get() { return _filename; }
	}

	property int Line
	{
		int get() { return _line; }
	}

	virtual System::String^ ToString() override
	{
		return System::String::Format(L"OpenCV exception: Status = {0}\r\n\tMessage = {1}\r\n\tFunction = {2}\r\n\tFilename = {3}\r\n\tLine = {4}", 
			this->Status, this->Message, this->Function, this->FileName, this->Line);
	}

private:
	ErrorCode _status;
	System::String^ _func;
	System::String^ _filename;
	int _line;
};
//////////////////////////////////////////////////////////////////////////
NAMESPACE_END
//////////////////////////////////////////////////////////////////////////